package ciyuan.Item.SkillBook;

import ciyuan.Item.ItemGroups;
import ciyuan.Item.TypeInterface.SkillBookType;
import ciyuan.Player.Skill.Passive.AddStar;
import ciyuan.Player.Skill.SkillUtils;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.item.ArmorStandEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.util.DamageSource;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceContext;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.server.ServerWorld;

import java.util.concurrent.ConcurrentHashMap;

public class StarChop extends SkillBookType {

    private static final ConcurrentHashMap<String, Integer> count = new ConcurrentHashMap<>();

    public StarChop() {
        super(new Properties().tab(ItemGroups.SkillBook));
    }

    @Override
    public void keyDown(PlayerEntity playerEntity) {
        SkillUtils.setSkillColdInterval(playerEntity, this, 10);

        if (count.containsKey(playerEntity.getName().getString())) {
            if (playerEntity.level.isClientSide) {
                count.put(playerEntity.getName().getString(), count.get(playerEntity.getName().getString()) + 1);
                SkillUtils.setSkillPercentage(playerEntity, count.get(playerEntity.getName().getString()), 250);
                return;
            } else if (count.get(playerEntity.getName().getString())>1){
                count.put(playerEntity.getName().getString(),count.get(playerEntity.getName().getString())+1);
                SkillUtils.setSkillPercentage(playerEntity,count.get(playerEntity.getName().getString()),250);
                return;
            }
        }
        count.put(playerEntity.getName().getString(),1);
        StarChop that = this;

        SkillUtils.THREAD_POOL_EXECUTOR.execute(new Runnable() {
            @Override
            public void run() {
                long time = System.currentTimeMillis();
                int lastCount=0;
                while (System.currentTimeMillis()-time<5000) {
                    if (!count.containsKey(playerEntity.getName().getString())) {
                        break;
                    }
                    if (count.get(playerEntity.getName().getString())==lastCount || count.get(playerEntity.getName().getString())>=250) {
                        lastCount = count.get(playerEntity.getName().getString());
                        break;
                    } else {
                        lastCount = count.get(playerEntity.getName().getString());
                        SkillUtils.sleep(200);
                    }
                }

                SkillUtils.setSkillPercentage(playerEntity,0,250);
                count.remove(playerEntity.getName().getString());

                if (lastCount<50) {
                    return;
                }

                boolean attacked = false;
                for (int i=0;i<(lastCount/50);i++) {
                    BlockPos blockPos = SkillUtils.getPlayerSee(playerEntity.level, playerEntity, RayTraceContext.FluidMode.SOURCE_ONLY, i + 2).getBlockPos();
                    double d0 = -MathHelper.sin(playerEntity.yRot * ((float) Math.PI / 180F));
                    double d1 = MathHelper.cos(playerEntity.yRot * ((float) Math.PI / 180F));
                    if (playerEntity.level instanceof ServerWorld) {
                        ((ServerWorld) playerEntity.level).sendParticles(ParticleTypes.SWEEP_ATTACK, blockPos.getX() + d0, blockPos.getY(), blockPos.getZ() + d1, 0, d0, 0.0D, d1, 0.0D);
                    }
                    playerEntity.level.playSound(null, playerEntity.getX(), playerEntity.getY(), playerEntity.getZ(), SoundEvents.PLAYER_ATTACK_SWEEP, playerEntity.getSoundSource(), 1.0F, 1.0F);
                    for (LivingEntity livingentity : playerEntity.level.getEntitiesOfClass(LivingEntity.class, new AxisAlignedBB(
                            blockPos.getX() + 2, blockPos.getY() + 2, blockPos.getZ() + 2, blockPos.getX() - 2, blockPos.getY() - 2, blockPos.getZ() - 2
                    ))) {
                        if (livingentity != playerEntity && !playerEntity.isAlliedTo(livingentity) && (!(livingentity instanceof ArmorStandEntity) || !((ArmorStandEntity) livingentity).isMarker()) && blockPos.distSqr(livingentity.getX(), livingentity.getY(), livingentity.getZ(), false) < 18.0D) {
                            livingentity.knockback(0.2F, MathHelper.sin(playerEntity.yRot * ((float) Math.PI / 180F)), -MathHelper.cos(playerEntity.yRot * ((float) Math.PI / 180F)));
                            if (playerEntity.level instanceof ServerWorld) {
                                livingentity.hurt(DamageSource.playerAttack(playerEntity), 10);
                                AddStar.addCount(playerEntity);
                            }
                            attacked=true;
                        }
                    }
                    SkillUtils.sleep(300);
                }
                if (attacked) {
                    playerEntity.knockback(1.5F, MathHelper.sin(playerEntity.yRot * ((float) Math.PI / 180F)), -MathHelper.cos(playerEntity.yRot * ((float) Math.PI / 180F)));
                    if (playerEntity.level instanceof ServerWorld) {
                        SkillUtils.addHitListener(playerEntity,that::onHit,40);
                    }
                }
            }
        });

        SkillUtils.saveSkillCastTime(playerEntity,this);
    }

    public void onHit(PlayerEntity playerEntity, Entity target) {
        target.hurt(DamageSource.playerAttack(playerEntity),10F);
    }

    @Override
    public String getSkillCastName() {
        return "starChop";
    }

    @Override
    public ITextComponent getSkillDescription() {
        return new TranslationTextComponent("ciyuan.skill.desc.10");
    }

    @Override
    public ITextComponent getSkillName() {
        return new TranslationTextComponent("ciyuan.skill.name.10");
    }
}
